package com.dobest.aspectdemo;

import com.sun.javafx.binding.StringFormatter;
import javafx.beans.binding.StringExpression;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @Package: com.dobest.aspectdemo
 * @author: hujiansong
 * @date: 2018/8/6 11:17
 * @version: V1.0
 */
@Slf4j
@Component
@Aspect
public class ParamCheckAspect {

    @Pointcut("execution(public * com.dobest.aspectdemo.web..*.*(..))")
    public void check() {

    }

    @Before("check()")
    public void doBefore(JoinPoint joinPoint) {

    }

    @Around("check()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        log.info("{}", method);



        Annotation[][] parameterAnnotations = method.getParameterAnnotations();

        // 获取参数名字
        String[] parameterNames = methodSignature.getParameterNames();

        // 获取参数类型
        Class[] parameterTypes = methodSignature.getParameterTypes();

        // 参数值
        Object[] args = joinPoint.getArgs();

        for (int i = 0; i < parameterAnnotations.length; i++) {
            Annotation[] annotations = parameterAnnotations[i];
            for (int j = 0; j < annotations.length; j++) {
                Annotation an = annotations[j];
                if (an instanceof ParamCheck) {
                    ParamCheck check = (ParamCheck) an;
                    boolean notNull = check.notNull();
                    if (notNull) {
                        this.doCheck(parameterNames[i], parameterTypes[i], args[i]);

                    }
                }
            }
        }



        return joinPoint.proceed();
    }

    private void doCheck(String parameterName, Class parameterType, Object arg) {
        log.info("parameterName = {} parameterType = {} arg = {} ", parameterName, parameterType, arg);
        throw new ParamNullException(parameterName + "Cannot be null");
    }


}
